package com.wuhunyu.service.impl;

import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.*;
import com.google.gson.Gson;
import com.wuhunyu.commonutils.check.Check;
import com.wuhunyu.commonutils.result.CommonResult;
import com.wuhunyu.service.VideoService;
import com.wuhunyu.servicebase.exception.Assert;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 视频上传实现类
 *
 * @author wuhunyu
 * @version 1.0
 * @date 2021-01-20 14:56
 */
@Service("videoService")
@ConfigurationProperties(prefix = "aliyun.video")
@PropertySource("classpath:application.yml")
public class VideoServiceImpl implements VideoService {

    @Value("${regionId}")
    private String regionId;

    @Value("${endpoint}")
    private String accessKeyId;

    @Value("${accessKeyId}")
    private String accessKeySecret;

    private Map<String, Object> map = new HashMap<>(16);

    /**
     * 构造DefaultAcsClient对象
     * @param accessKeyId
     * @param accessKeySecret
     * @return
     * @throws ClientException
     */
    public DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }

    @Override
    public CommonResult addVideo(MultipartFile file) {
        // 校验参数
        Assert.isRight(Check.isBlank(file), "文件异常");
        // 随机生成新的文件名称
        String title = UUID.randomUUID().toString().replaceAll("-", "");
        UploadStreamRequest request = null;
        try {
            // 获取文件的源名称
            String fileName = file.getOriginalFilename();
            request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, fileName, file.getInputStream());
        } catch (IOException e) {
            Assert.isRight(true, "文件流异常");
        }
        UploadVideoImpl uploader = new UploadVideoImpl();
        UploadStreamResponse response = uploader.uploadStream(request);
        if (response.isSuccess()) {
            // 上传成功
            map.put("videoId", response.getVideoId());
            map.put("title", title);
            return CommonResult.success("视频上传成功", map);
        }
        return CommonResult.error("视频上传失败");
    }

    @Override
    public CommonResult getVideo(String videoId) {
        // 校验视频id
        Assert.isRight(Check.isBlank(videoId), "视频id不能为空");
        DefaultAcsClient client = null;
        try {
            client = this.initVodClient(accessKeyId, accessKeySecret);
        } catch (ClientException e) {
            Assert.isRight(true, "构建DefaultAcsClient对象失败");
        }
        // 创建获取视频地址request和response
        GetPlayInfoRequest playInfoRequest = new GetPlayInfoRequest();
        // 向request对象中设置视频id
        playInfoRequest.setVideoId(videoId);
        // 调用初始化对象里面的方法，传递request，获取数据
        GetPlayInfoResponse playInfoResponse = null;
        try {
            playInfoResponse = client.getAcsResponse(playInfoRequest);
        } catch (ClientException e) {
            Assert.isRight(true, "获取GetPlayInfoResponse对象失败");
        }
        List<GetPlayInfoResponse.PlayInfo> playInfoList = playInfoResponse.getPlayInfoList();
        // 校验结果集
        Assert.isRight(Check.isBlank(playInfoList), "视频不存在");
        // 封装信息
        // 播放地址
        map.put("url", playInfoList.get(0).getPlayURL());
        // 视频标题
        map.put("title", playInfoResponse.getVideoBase().getTitle());
        // 获取视频的详情信息
        getVideoInfo(videoId);
        return CommonResult.success("获取视频信息成功", map);
    }

    /**
     * 获取上传视频的大小，时长，状态信息
     *
     */
    public void getVideoInfo(String videoId) {
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        GetVideoInfoRequest request = new GetVideoInfoRequest();
        request.setVideoId(videoId);
        try {
            GetVideoInfoResponse response = client.getAcsResponse(request);
            // 封装数据
            GetVideoInfoResponse.Video video = response.getVideo();
            // 视频大小
            map.put("size", video.getSize() / 1024.0 / 1024.0);
            // 视频时长
            map.put("duration", video.getDuration());
            // 视频状态信息
            map.put("status", video.getStatus());
        } catch (ClientException e) {
            Assert.isRight(true, "获取视频详情信息失败");
        }
    }

    @Override
    public CommonResult deleteVideo(String videoId) {
        // 校验视频id
        Assert.isRight(Check.isBlank(videoId), "视频id不能为空");
        // 执行删除操作
        DefaultAcsClient client = null;
        try {
            client = initVodClient(accessKeyId, accessKeySecret);
            DeleteVideoRequest request = new DeleteVideoRequest();
            //支持传入多个视频ID，多个用逗号分隔
            request.setVideoIds(videoId);
            client.getAcsResponse(request);
        } catch (ClientException e) {
            Assert.isRight(true, "视频删除失败");
        }
        return CommonResult.success("视频删除成功");
    }

    @Override
    public CommonResult deleteVideos(List<String> videoIds) {
        // 校验视频id
        Assert.isRight(Check.isBlank(videoIds), "视频id不能为空");
        // 执行删除操作
        DefaultAcsClient client = null;
        try {
            client = initVodClient(accessKeyId, accessKeySecret);
            DeleteVideoRequest request = new DeleteVideoRequest();
            //支持传入多个视频ID，多个用逗号分隔
            String ids = StringUtils.join(videoIds.toArray(), ",");
            request.setVideoIds(ids);
            client.getAcsResponse(request);
        } catch (ClientException e) {
            Assert.isRight(true, "视频删除失败");
        }
        return CommonResult.success("视频删除成功");
    }

    @Override
    public CommonResult getPlayAuth(String videoId) {
        // 校验参数
        Assert.isRight(Check.isBlank(videoId), "视频id不能为空");
        // 创建初始化对象
        DefaultAcsClient client = null;
        try {
            client = initVodClient(accessKeyId, accessKeySecret);
        } catch (ClientException e) {
            Assert.isRight(true, "获取视频播放凭证失败");
        }
        // 创建获取凭证的request和response对象
        GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
        // 设置视频id
        request.setVideoId(videoId);
        // 获取视频凭证
        GetVideoPlayAuthResponse response = null;
        try {
            response = client.getAcsResponse(request);
        } catch (ClientException e) {
            Assert.isRight(true, "获取视频播放凭证失败");
        }
        String playAuth = response.getPlayAuth();
        // 封装结果
        Map<String, Object> map = new HashMap<>(16);
        map.put("auth", playAuth);
        return CommonResult.success("获取视频播放凭证成功", map);
    }
}
